home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 4 / Apprentice-Release4.iso / Source Code / C / Applications / SML⁄NJ 93+ / Documentation / examples / textbooks / four_lectures / interp3.sml < prev    next >
Encoding:
Text File  |  1995-12-30  |  14.9 KB  |  549 lines  |  [TEXT/R*ch]

  1. (* interp3.sml , a more efficient (?) 
  2.    implementation of types and substitutuions *)
  3.  
  4. signature INTERPRETER=
  5.    sig
  6.       val interpret: string -> string
  7.       val eval: bool ref
  8.       and tc  : bool ref
  9.    end;
  10.  
  11.                   (* syntax *)
  12.  
  13. signature EXPRESSION =
  14.    sig
  15.       datatype Expression =
  16.          SUMexpr of Expression * Expression   |
  17.          DIFFexpr of Expression * Expression   |
  18.          PRODexpr of Expression * Expression   |
  19.          BOOLexpr of bool   |
  20.          EQexpr of Expression * Expression   |
  21.          CONDexpr of Expression * Expression * Expression   |
  22.          CONSexpr of Expression * Expression   |
  23.          LISTexpr of Expression list   |
  24.          DECLexpr of string * Expression * Expression   |
  25.          RECDECLexpr of string * Expression * Expression   |
  26.          IDENTexpr of string   |
  27.          LAMBDAexpr of string * Expression   |
  28.          APPLexpr of Expression * Expression   |
  29.          NUMBERexpr of int
  30.    end
  31.  
  32.  
  33.               (* parsing *)
  34.  
  35. signature PARSER =
  36.    sig
  37.       structure E: EXPRESSION
  38.  
  39.       exception Lexical of string
  40.       exception Syntax of string
  41.  
  42.       val parse: string -> E.Expression
  43.    end
  44.  
  45.  
  46.                         (* environments *)
  47.  
  48. signature ENVIRONMENT =
  49.    sig
  50.       type 'object Environment
  51.  
  52.       exception Retrieve of string
  53.  
  54.       val emptyEnv: 'object Environment
  55.       val declare: string * 'object * 'object Environment -> 'object Environment
  56.       val retrieve: string * 'object Environment -> 'object
  57.    end
  58.  
  59.                         (* evaluation *)
  60. signature VALUE =
  61.    sig
  62.       type Value
  63.       exception Value
  64.  
  65.       val mkValueNumber: int -> Value
  66.           and unValueNumber: Value -> int
  67.  
  68.       val mkValueBool: bool -> Value
  69.           and unValueBool: Value -> bool
  70.  
  71.       val ValueNil: Value
  72.       val mkValueCons: Value * Value -> Value
  73.           and unValueHead: Value -> Value
  74.           and unValueTail: Value -> Value
  75.  
  76.       val eqValue: Value * Value -> bool
  77.       val printValue: Value -> string
  78.    end
  79.  
  80.  
  81. signature EVALUATOR =
  82.    sig
  83.       structure Exp: EXPRESSION
  84.       structure Val: VALUE
  85.       exception Unimplemented
  86.       val evaluate: Exp.Expression -> Val.Value
  87.    end
  88.  
  89.                   (* type checking *)
  90. signature TYPE =
  91.    sig
  92.       eqtype tyvar
  93.       val freshTyvar: unit -> tyvar
  94.       type Type 
  95.   
  96.     (*constructors and decstructors*)
  97.       exception Type
  98.       val mkTypeInt: unit -> Type
  99.           and unTypeInt: Type -> unit
  100.  
  101.       val mkTypeBool: unit -> Type
  102.           and unTypeBool: Type -> unit
  103.  
  104.       val mkTypeList: Type -> Type
  105.           and unTypeList: Type -> Type
  106.  
  107.       val mkTypeTyvar: tyvar -> Type
  108.           and unTypeTyvar: Type -> tyvar
  109.  
  110.       type subst
  111.       val Id: subst
  112.     (*elementary substitution*)
  113.       val mkSubst: tyvar*Type -> subst
  114.     (*composition*)
  115.       val O: subst * subst -> subst 
  116.     (*application*)
  117.       val on : subst * Type -> Type
  118.  
  119.     (*printing*)
  120.       val prType: Type->string
  121.    end
  122.  
  123.  
  124.  
  125. signature TYPECHECKER =
  126.    sig
  127.       structure Exp: EXPRESSION
  128.       structure Type: TYPE
  129.       exception NotImplemented of string
  130.       exception TypeError of Exp.Expression * string
  131.       val typecheck: Exp.Expression -> Type.Type
  132.    end;
  133.  
  134.                   (* the interpreter*)
  135.  
  136. functor Interpreter
  137.    (structure Ty: TYPE
  138.     structure Value : VALUE
  139.     structure Parser: PARSER
  140.     structure TyCh: TYPECHECKER
  141.     structure Evaluator:EVALUATOR
  142.       sharing Parser.E = TyCh.Exp = Evaluator.Exp
  143.           and TyCh.Type = Ty
  144.           and Evaluator.Val = Value
  145.    ): INTERPRETER=
  146.  
  147. struct
  148.   val eval= ref true    (* toggle for evaluation *)
  149.   and tc  = ref true    (* toggle for type checking *)
  150.   fun interpret(str)=
  151.     let val abstsyn= Parser.parse str
  152.         val typestr= if !tc then Ty.prType(TyCh.typecheck abstsyn)
  153.                      else "(disabled)"
  154.         val valuestr= if !eval then 
  155.                          Value.printValue(Evaluator.evaluate abstsyn)
  156.                       else "(disabled)"
  157.              
  158.     in  valuestr ^ " : " ^ typestr 
  159.     end
  160.     handle Evaluator.Unimplemented => "Evaluator not fully implemented"
  161.          | TyCh.NotImplemented msg => "Type Checker not fully implemented " ^ msg
  162.          | Value.Value   => "Run-time error"
  163.          | Parser.Syntax msg => "Syntax Error: " ^ msg
  164.          | Parser.Lexical msg=> "Lexical Error: " ^ msg
  165.          | TyCh.TypeError(_,msg)=> "Type Error: " ^ msg
  166. end;
  167.                
  168.                     (* the evaluator *)
  169.  
  170. functor Evaluator
  171.   (structure Expression: EXPRESSION
  172.    structure Value: VALUE):EVALUATOR=
  173.  
  174.    struct
  175.       structure Exp= Expression
  176.       structure Val= Value
  177.       exception Unimplemented
  178.  
  179.       local
  180.          open Expression Value
  181.          fun evaluate exp =
  182.             case exp
  183.               of BOOLexpr b => mkValueBool b
  184.                | NUMBERexpr i => mkValueNumber i
  185.                | SUMexpr(e1, e2) =>
  186.                     let val e1' = evaluate e1
  187.                         val e2' = evaluate e2
  188.                     in
  189.                        mkValueNumber(unValueNumber e1' + unValueNumber e2')
  190.                     end
  191.  
  192.                | DIFFexpr(e1, e2) =>
  193.                     let val e1' = evaluate e1
  194.                         val e2' = evaluate e2
  195.                     in
  196.                        mkValueNumber(unValueNumber e1' - unValueNumber e2')
  197.                     end
  198.  
  199.                | PRODexpr(e1, e2) =>
  200.                     let val e1' = evaluate e1
  201.                         val e2' = evaluate e2
  202.                     in
  203.                        mkValueNumber(unValueNumber e1' * unValueNumber e2')
  204.                     end
  205.  
  206.                | EQexpr _ => raise Unimplemented
  207.                | CONDexpr _ => raise Unimplemented
  208.                | CONSexpr _ => raise Unimplemented
  209.                | LISTexpr _ => raise Unimplemented
  210.                | DECLexpr _ => raise Unimplemented
  211.                | RECDECLexpr _ => raise Unimplemented
  212.                | IDENTexpr _ => raise Unimplemented
  213.                | LAMBDAexpr _ => raise Unimplemented
  214.                | APPLexpr _ => raise Unimplemented
  215.  
  216.       in
  217.          val evaluate = evaluate
  218.       end
  219.    end;
  220.  
  221.                         (* the type checker *)   
  222. signature UNIFY=
  223.    sig
  224.       structure Type: TYPE
  225.       exception NotImplemented of string
  226.       exception Unify
  227.       val unify: Type.Type * Type.Type -> Type.subst
  228.    end;
  229.  
  230. functor TypeChecker
  231.   (structure Ex: EXPRESSION
  232.    structure Ty: TYPE
  233.    structure Unify: UNIFY 
  234.     sharing Unify.Type = Ty
  235.   )=
  236. struct
  237.   infix on 
  238.   val (op on) = Ty.on
  239.   structure Exp = Ex
  240.   structure Type = Ty
  241.   exception NotImplemented of string
  242.   exception TypeError of Ex.Expression * string
  243.  
  244.   fun tc (exp: Ex.Expression): Ty.Type =
  245.    (case exp of
  246.       Ex.BOOLexpr b => Ty.mkTypeBool()
  247.     | Ex.NUMBERexpr _ => Ty.mkTypeInt()
  248.     | Ex.SUMexpr(e1,e2)  => checkIntBin(e1,e2)
  249.     | Ex.DIFFexpr(e1,e2) => checkIntBin(e1,e2)
  250.     | Ex.PRODexpr(e1,e2) => checkIntBin(e1,e2)
  251.     | Ex.LISTexpr [] =>
  252.          let val new = Ty.freshTyvar ()
  253.           in Ty.mkTypeList(Ty.mkTypeTyvar  new)
  254.          end
  255.     | Ex.LISTexpr(e::es) => tc (Ex.CONSexpr(e,Ex.LISTexpr es))
  256.     | Ex.CONSexpr(e1,e2) =>
  257.         let val t1 = tc e1
  258.             val t2 = tc e2
  259.             val new = Ty.freshTyvar ()
  260.             val newt= Ty.mkTypeTyvar new
  261.             val t2' = Ty.mkTypeList newt
  262.             val S1 = Unify.unify(t2, t2')
  263.                      handle Unify.Unify=> 
  264.                      raise TypeError(e2,"expected list type")
  265.  
  266.             val S2 = Unify.unify(S1 on newt,S1 on t1)
  267.                      handle Unify.Unify=>
  268.                      raise TypeError(exp,"element and list have different types")
  269.          in S2 on (S1 on t2)
  270.         end
  271.     | Ex.EQexpr _ => raise NotImplemented "(equality)"
  272.     | Ex.CONDexpr _ => raise NotImplemented "(conditional)"
  273.     | Ex.DECLexpr _ => raise NotImplemented "(declaration)"
  274.     | Ex.RECDECLexpr _ => raise NotImplemented "(rec decl)"
  275.     | Ex.IDENTexpr _   => raise NotImplemented "(identifier)"
  276.     | Ex.LAMBDAexpr _  => raise NotImplemented "(function)"
  277.     | Ex.APPLexpr _ => raise NotImplemented    "(application)"
  278.  
  279.    )handle Unify.NotImplemented msg => raise NotImplemented msg
  280.        
  281.   and checkIntBin(e1,e2) =
  282.     let val t1 = tc e1
  283.         val _  = Ty.unTypeInt t1
  284.                  handle Ty.Type=> raise TypeError(e1,"expected int")
  285.         val t2 = tc e2
  286.         val _  = Ty.unTypeInt t2
  287.                  handle Ty.Type=> raise TypeError(e2,"expected int")
  288.      in Ty.mkTypeInt()
  289.     end;
  290.  
  291.   val typecheck = tc
  292.  
  293. end; (*TypeChecker*)
  294.  
  295.  
  296. functor Unify(Ty:TYPE):UNIFY=
  297. struct
  298.    structure Type = Ty
  299.    exception NotImplemented of string
  300.    exception Unify
  301.  
  302.    fun occurs(tv:Ty.tyvar,t:Ty.Type):bool=
  303.      (Ty.unTypeInt t; false)              handle Ty.Type=>
  304.      (Ty.unTypeBool t; false)             handle Ty.Type=>
  305.      let val tv' = Ty.unTypeTyvar t
  306.      in  tv=tv'
  307.      end                                  handle Ty.Type=>
  308.      let val t'  = Ty.unTypeList t
  309.      in  occurs(tv,t')
  310.      end                                  handle Ty.Type=>
  311.      raise NotImplemented "(the occur check)"
  312.  
  313.  
  314.    fun unify(t,t')=
  315.    let val tv = Ty.unTypeTyvar t
  316.     in let val tv' = Ty.unTypeTyvar t'
  317.         in Ty.mkSubst(tv,t')
  318.        end                                handle Ty.Type=>
  319.        if occurs(tv,t') then raise Unify
  320.        else Ty.mkSubst(tv,t')
  321.    end                                  handle Ty.Type=>
  322.    let val tv' = Ty.unTypeTyvar t'
  323.     in if occurs(tv',t) then raise Unify
  324.        else Ty.mkSubst(tv',t)
  325.    end                           handle Ty.Type=>
  326.    let val _ = Ty.unTypeInt t
  327.     in let val _ = Ty.unTypeInt t'
  328.         in Ty.Id
  329.        end handle Ty.Type=> raise Unify
  330.    end                    handle Ty.Type =>
  331.    let val _ = Ty.unTypeBool t
  332.     in let val _ = Ty.unTypeBool t'
  333.         in Ty.Id
  334.        end handle Ty.Type=> raise Unify
  335.    end                    handle Ty.Type=>
  336.    let val t = Ty.unTypeList t
  337.     in let val t' = Ty.unTypeList t'
  338.         in unify(t,t')
  339.        end handle Ty.Type => raise Unify
  340.    end                     handle Ty.Type=>
  341.    raise NotImplemented "(unify)"     
  342.  
  343. end; (*Unify*)
  344.   
  345.                      (* the basics -- nullary functors *)
  346.  
  347. functor AppType():TYPE =
  348. struct
  349.   type tyvar = int
  350.   val freshTyvar =
  351.       let val r= ref 0 in fn()=>(r:= !r +1; !r) end
  352.   datatype Type = INT
  353.                 | BOOL
  354.                 | LIST of Type
  355.                 | TYVAR of tyvar  
  356.  
  357.   exception Type
  358.  
  359.   fun mkTypeInt() = INT
  360.   and unTypeInt(INT)=()
  361.     | unTypeInt(_)= raise Type
  362.  
  363.   fun mkTypeBool() = BOOL
  364.   and unTypeBool(BOOL)=()
  365.     | unTypeBool(_)= raise Type
  366.  
  367.   fun mkTypeList(t)=LIST t
  368.   and unTypeList(LIST t)= t
  369.     | unTypeList(_)= raise Type
  370.  
  371.   fun mkTypeTyvar tv = TYVAR tv
  372.   and unTypeTyvar(TYVAR tv) = tv
  373.     | unTypeTyvar _ = raise Type
  374.   
  375.   type subst = Type -> Type
  376.  
  377.   fun Id x = x
  378.   fun mkSubst(tv,ty)=
  379.      let fun su(TYVAR tv')= if tv=tv' then ty else TYVAR tv'
  380.          |   su(INT) = INT
  381.          |   su(BOOL)= BOOL
  382.          |   su(LIST ty') = LIST (su ty')
  383.       in su
  384.      end
  385.  
  386.  
  387.   val O = (op o)
  388.  
  389.   fun on(S,t)= S(t)
  390.  
  391.   fun intToString(i:int)=  (if i<0 then " -" else "")^ natToString (abs i)
  392.   and natToString(n:int)=
  393.       let val d = n div 10 in
  394.         if d = 0 then chr(ord"0" + n)
  395.         else natToString(d)^ chr(ord"0" + (n mod 10))
  396.       end
  397.  
  398.   fun prType INT = "int"
  399.   |   prType BOOL= "bool"
  400.   |   prType (LIST ty) = "(" ^ prType ty ^ ")list"
  401.   |   prType (TYVAR tv) = "a" ^ intToString tv
  402. end;
  403.  
  404.  
  405.  
  406. functor ImpType():TYPE =
  407. struct
  408.   datatype 'a option = NONE | SOME of 'a
  409.  
  410.   datatype Type = INT
  411.                 | BOOL
  412.                 | LIST of Type
  413.                 | TYVAR of tyvar
  414.  
  415.   withtype tyvar =  Type option ref
  416.  
  417.   type tyvar = Type option ref
  418.  
  419.   fun freshTyvar() = ref (NONE)
  420.  
  421.   exception Type
  422.  
  423.   fun mkTypeInt() = INT
  424.   and unTypeInt(INT)=()
  425.     | unTypeInt(TYVAR(r as(ref (SOME (TYVAR tv)))))=
  426.        (r:= !tv; unTypeInt(TYVAR r))
  427.     | unTypeInt(TYVAR(ref (SOME t)))= unTypeInt t
  428.     | unTypeInt _ = raise Type
  429.  
  430.  
  431.   fun mkTypeBool() = BOOL
  432.   and unTypeBool(BOOL)=()
  433.     | unTypeBool(TYVAR(r as(ref (SOME (TYVAR tv)))))=
  434.        (r:= !tv; unTypeBool(TYVAR r))
  435.     | unTypeBool(TYVAR(ref (SOME t)))= unTypeBool t
  436.     | unTypeBool(_)= raise Type
  437.  
  438.   fun mkTypeList(t)=LIST t
  439.   and unTypeList(LIST t)= t
  440.     | unTypeList(TYVAR(r as(ref (SOME (TYVAR tv)))))=
  441.        (r:= !tv; unTypeList(TYVAR r))
  442.     | unTypeList(TYVAR(ref (SOME t)))= unTypeList t
  443.     | unTypeList(_)= raise Type
  444.  
  445.   fun mkTypeTyvar tv = TYVAR tv
  446.   and unTypeTyvar(TYVAR (tv as (ref NONE))) = tv
  447.     | unTypeTyvar(TYVAR(r as(ref (SOME (TYVAR tv)))))=
  448.        (r:= !tv; unTypeTyvar(TYVAR r))
  449.     | unTypeTyvar _ = raise Type
  450.   
  451.   type subst = unit
  452.  
  453.   val Id = ();
  454.  
  455.   exception MkSubst;
  456.  
  457.   fun mkSubst(tv,ty)=
  458.      case tv of
  459.        ref(NONE) => tv:= (SOME ty)
  460.      | ref(SOME t) => raise MkSubst 
  461.  
  462.   fun O(S2,S1) = ()
  463.  
  464.   fun on(S,t)= t
  465.  
  466.   fun prType INT = "int"
  467.   |   prType BOOL= "bool"
  468.   |   prType (LIST ty) = "(" ^ prType ty ^ ")list"
  469.   |   prType (TYVAR (ref NONE)) = "a?" 
  470.   |   prType (TYVAR (ref (SOME t))) = prType t
  471. end;
  472.  
  473.  
  474.  
  475. functor Expression(): EXPRESSION =
  476.    struct
  477.       type 'a pair = 'a * 'a
  478.  
  479.       datatype Expression =
  480.          SUMexpr of Expression pair   |
  481.          DIFFexpr of Expression pair   |
  482.          PRODexpr of Expression pair   |
  483.          BOOLexpr of bool   |
  484.          EQexpr of Expression pair   |
  485.          CONDexpr of Expression * Expression * Expression   |
  486.          CONSexpr of Expression pair   |
  487.          LISTexpr of Expression list   |
  488.          DECLexpr of string * Expression * Expression   |
  489.          RECDECLexpr of string * Expression * Expression   |
  490.          IDENTexpr of string   |
  491.          LAMBDAexpr of string * Expression   |
  492.          APPLexpr of Expression * Expression   |
  493.          NUMBERexpr of int
  494.    end;
  495.  
  496. functor Value(): VALUE =
  497.    struct
  498.       type 'a pair = 'a * 'a
  499.  
  500.       datatype Value = NUMBERvalue of int   |
  501.                       BOOLvalue of bool   |
  502.                       NILvalue   |
  503.                       CONSvalue of Value pair
  504.  
  505.       exception Value
  506.  
  507.       val mkValueNumber = NUMBERvalue
  508.       val mkValueBool = BOOLvalue
  509.  
  510.       val ValueNil = NILvalue
  511.       val mkValueCons = CONSvalue
  512.  
  513.       fun unValueNumber(NUMBERvalue(i)) = i   |
  514.           unValueNumber(_) = raise Value
  515.  
  516.       fun unValueBool(BOOLvalue(b)) = b   |
  517.           unValueBool(_) = raise Value
  518.  
  519.       fun unValueHead(CONSvalue(c, _)) = c   |
  520.           unValueHead(_) = raise Value
  521.  
  522.       fun unValueTail(CONSvalue(_, c)) = c   |
  523.           unValueTail(_) = raise Value
  524.  
  525.       fun eqValue(c1, c2) = (c1 = c2)
  526.  
  527.                 (* Pretty-printing *)
  528.       fun intToString(i:int)=  (if i<0 then " -" else "")^ natToString (abs i)
  529.       and natToString(n:int)=
  530.           let val d = n div 10 in
  531.             if d = 0 then chr(ord"0" + n)
  532.             else natToString(d)^ chr(ord"0" + (n mod 10))
  533.           end
  534.       fun printValue(NUMBERvalue(i)) = intToString(i)   |
  535.           printValue(BOOLvalue(true)) = "true"   |
  536.           printValue(BOOLvalue(false)) = "false"   |
  537.           printValue(NILvalue) = "[]"   |
  538.           printValue(CONSvalue(cons)) = "[" ^ printValueList(cons) ^ "]"
  539.           and printValueList(hd, NILvalue) = printValue(hd)   |
  540.               printValueList(hd, CONSvalue(tl)) =
  541.                  printValue(hd) ^ ", " ^ printValueList(tl)   |
  542.               printValueList(_) = raise Value
  543.    end;
  544.  
  545.  
  546.  
  547.  
  548.  
  549.